package com.hexun.vmcenter.filter;

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.Provider;

import org.jboss.resteasy.core.Headers;
import org.jboss.resteasy.core.ResourceMethodInvoker;
import org.jboss.resteasy.core.ServerResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.hexun.vmcenter.anno.Frequency;
import com.hexun.vmcenter.service.RateHandler;

@Component
@Provider
public class MyInterceptor implements ContainerRequestFilter {

	private static final Logger log = LoggerFactory.getLogger(MyInterceptor.class);

	@Context
	HttpServletRequest request;

	@Autowired
    private RateHandler rateHandler;
	
	private static final ServerResponse ACCESS_FORBIDDEN = new ServerResponse("访问频率超过限制", 403, new Headers<Object>());

	public void filter(ContainerRequestContext requestContext) throws IOException {
		ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) requestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
		Method method = methodInvoker.getMethod();
		String className = method.getDeclaringClass().getName();
		if(method.isAnnotationPresent(Frequency.class)){
			String methodName = method.getName();
			Frequency mf = method.getAnnotation(Frequency.class);
			String ip = getLocalIP(request);
			String requestMethod = ip + "|" + className + "|" + methodName + "|";
			try {
				boolean limit = rateHandler.isLimit(requestMethod, System.currentTimeMillis(), mf.limit(), mf.rate());
				log.debug(limit + "");
				System.out.println("*********************" + limit);
				if(limit){
					requestContext.abortWith(ACCESS_FORBIDDEN);
					return;
				}
			} catch (Exception e) {
				log.error(e.getMessage());
				throw new RuntimeException(e);
			}
		}
	}

	private String getLocalIP(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

}
